package thread.communicate.tradition.communication;

import thread.unsafeExample.SafeAccount;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;

/**
 * 如果每个线程执行的代码相同，可以使用同一个Runnable对象，这个Runnable对象中保存那个共享对象，便可完成线程间的通讯。
 * 注意：线程安全的问题，交给synchronized代码块完成，该示例主要体现线程间的通讯。
 *
 * 语法： 静态内部类只能在 类的内部定义
 * Created by E440 on 2017/4/19.
 */
public class SameRunnableCommunication {
    static boolean[] flag={true};


    public static void main(String[] args) throws FileNotFoundException {
        PrintStream ps=new PrintStream(new FileOutputStream("d:/sameRunnableCommunicate.txt"));
        System.setOut(ps);

        final SafeAccount safeAccount=new SafeAccount(1,100);
        final double drawMoney=10;
        final double saveMoney=5;

        SameRunnableCommunication.DrawRunnable drawRunnable=new SameRunnableCommunication.DrawRunnable(safeAccount,drawMoney);

        //取钱线程1
        new Thread(drawRunnable).start();

        //取钱线程2
        new Thread(drawRunnable).start();

        //存钱线程
       new Thread(new Runnable() {
            @Override
            public void run() {
                while (flag[0]){
                    if(safeAccount.getAmount()<0){
                        break;
                    }
                    if(safeAccount.getAmount()>150){
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    safeAccount.save(saveMoney);
                   // System.out.println(Thread.currentThread().getName()+" : "+ safeAccount);
                }
            }
        }).start();
    }


    //静态内部类：取钱Runnable
     static class   DrawRunnable implements Runnable {
        //成员变量，线程间共享数据，通过构造函数传入
        private SafeAccount safeAccount=null;

        double drawMoney;

        public DrawRunnable(SafeAccount safeAccount,double drawMoney) {
            this.safeAccount=safeAccount;
            this.drawMoney=drawMoney;
        }


        @Override
        public void run() {
            while(flag[0]){
                safeAccount.draw(drawMoney);
                //System.out.println("draw thread "+Thread.currentThread().getName()+" : "+ safeAccount);
                if(safeAccount.getAmount()<0){
                    flag[0]=false;
                }
            }

        }
    }
}
